﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once

#include "GcmpGuiMainFrame.h"
#include "IStatusBarPanel.h"
#include "OwnerPtr.h"
#include "IControlDefinitionLibraryEventHandler.h"
#include <QWidget>

#include <vector>

class QHBoxLayout;

namespace gcmp
{

class StatusBarCtrl;
class IStatusBarCtrl;

// 状态栏面板
class GCMP_GUI_MAIN_FRAME_EXPORT StatusBarPanelImpl : public QWidget, public IStatusBarPanel, public IControlDefinitionLibraryEventHandler
{
public:
    StatusBarPanelImpl(const std::wstring& name, int minWidth = 0, int stretch = 0);

    ~StatusBarPanelImpl() final;

    std::wstring GetPanelId() const final;

    IControl* AddButton(OwnerPtr<ICommandButtonDefinition> pButtonDefinition) final;

    IControl* AddLineEdit(OwnerPtr<ILineEditDefinition> pLineEditDefinition) final;

    IControl* AddComboBox(OwnerPtr<IComboBoxDefinition> pComboBoxDefinition) final;

    IControl* AddButtonMenu(OwnerPtr<ICommandButtonMenuDefinition> pButtonMenuDefinition) final;

    IControl* AddCheckBoxGroup(OwnerPtr<ICheckBoxGroupDefinition> pCheckBoxGroupDefinition) final;

    IControl* AddRadioButtonGroup(OwnerPtr<IRadioButtonGroupDefinition> pRadioButtonGroupDefinition) final;

    IControl* AddLabel(OwnerPtr<ILabelDefinition> pLabelDefinition) final;

    IControl* AddProgressBar(OwnerPtr<IProgressBarDefinition> pProgressBarDefinition) final;

    IControl* InsertButton(const std::wstring& followingControlDefinitionId, OwnerPtr<ICommandButtonDefinition> pButtonDefinition) final;

    IControl* InsertLineEdit(const std::wstring& followingControlDefinitionId, OwnerPtr<ILineEditDefinition> pLineEditDefinition) final;

    IControl* InsertComboBox(const std::wstring& followingControlDefinitionId, OwnerPtr<IComboBoxDefinition> pComboBoxDefinition) final;

    IControl* InsertButtonMenu(const std::wstring& followingControlDefinitionId, OwnerPtr<ICommandButtonMenuDefinition> pButtonMenuDefinition) final;

    IControl* InsertCheckBoxGroup(const std::wstring& followingControlDefinitionId, OwnerPtr<ICheckBoxGroupDefinition> pCheckBoxGroupDefinition) final;

    IControl* InsertRadioButtonGroup(const std::wstring& followingControlDefinitionId, OwnerPtr<IRadioButtonGroupDefinition> pRadioButtonGroupDefinition) final;

    IControl* InsertLabel(const std::wstring& followingControlDefinitionId, OwnerPtr<ILabelDefinition> pLabelDefinition) final;

    IControl* InsertProgressBar(const std::wstring& followingControlDefinitionId, OwnerPtr<IProgressBarDefinition> pProgressBarDefinition) final;

    IControl* GetControl(const std::wstring& id) const final;

    std::vector<IControl*> GetAllControls() const final;

    bool DeleteControl(const std::wstring& id) final;

    void DeleteAllControls() final;

    virtual void On(IControlDefinitionLibraryEventArgs* pArgs) override;

    virtual void UpdateControlStatus() override;

    int GetStretch() const;
private:
    template<typename ControlDefinitionType>
    IControl* AddControl(OwnerPtr<ControlDefinitionType> pControlDefinition);
    
    template<typename ControlDefinitionType>
    IControl* InsertControl(const std::wstring& followingControlDefinitionId, OwnerPtr<ControlDefinitionType> pControlDefinition);

    template<typename ControlGroupDefinitionType>
    IControl* AddControlGroup(OwnerPtr<ControlGroupDefinitionType> pControlGroupDefinition);

    template<typename ControlGroupDefinitionType>
    IControl* InsertControlGroup(const std::wstring& followingControlDefinitionId, OwnerPtr<ControlGroupDefinitionType> pControlGroupDefinition);

    // 获取pControl对应的第一个Qt控件在m_pHBoxLayout中的index
    // 目前QtRadioButtonGroup和QtCheckBoxGroup分别对应着多个Qt控件
    int GetFirstQWidgetIndex(const IControl* pControl) const;

private:
    std::vector<OwnerPtr<IControl>> m_controls;
    std::wstring m_name;
    int m_minWidth;
    int m_stretch;      //是否延展长度

    QHBoxLayout* m_pHBoxLayout;
};

}   // end namespace gcmp
